package com.smsc.headend.task.engine.handler.impl.collection.strategy;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.smsc.headend.module.asset.entity.Meter;
import com.smsc.headend.module.data.dto.DataItemDTO;
import com.smsc.headend.module.data.entity.RdMeterReadsLp;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.module.task.dto.TaskReadData;
import com.smsc.headend.task.engine.po.CollectDataDetailBo;
import com.smsc.headend.task.engine.service.collection.RecollectTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

import static com.smsc.headend.task.engine.handler.impl.collection.ReadLoadProfileBufferHandler.RECOLLECT_TASK_SEQ;

@Slf4j
public class AutoRecollectionStrategy implements CollectionStrategy {

    @Autowired
    RecollectTaskService recollectTaskService;


    @Override
    public List<RdMeterReadsLp> filterCollectionData(Task task, AtomicTask atomicTask, Map<String, Object> param, List<RdMeterReadsLp> meterReadsCol) {
        String recollectTaskSeq = param.get(RECOLLECT_TASK_SEQ) == null ? null : String.valueOf(param.get(RECOLLECT_TASK_SEQ));
        if (StringUtils.isEmpty(recollectTaskSeq)) {
            return Lists.emptyList();
        }

        //判断目标点是否已经返回,如果已返回，则将config_auto_recollect
        String targetPoint = MapUtil.get(param, "targetPoint", String.class);
        String executeTime = MapUtil.get(param, "executeTime", String.class);
        String interval = MapUtil.get(param, "interval", String.class);
        CollectDataDetailBo collectDataDetailBo = recollectTaskService.handleRecollect(meterReadsCol, recollectTaskSeq, targetPoint, Convert.toInt(executeTime), interval);
        log.info("recollect: new fetch data comId={},meterId={},recollectSeq={},executeTime={},collectDetail={}", task.getComId(), task.getMeterId(), recollectTaskSeq, executeTime, JSONUtil.toJsonStr(collectDataDetailBo));
        if (collectDataDetailBo.getLeftPointCount() > 0 || collectDataDetailBo.getLeftPointCount() == null) {
            recollectTaskService.rescheduleRecollectTask(task, collectDataDetailBo, Convert.toInt(executeTime));
        }
        return meterReadsCol.stream().filter(o -> collectDataDetailBo.getHitPointTv().contains(o.getTv())).collect(Collectors.toList());
    }

    @Override
    public int callback(Meter meter, TaskReadData readData, Task task, AtomicTask atomicTask, Map<String, Object> param, List<DataItemDTO> dataItemCosemList, List<RdMeterReadsLp> filteredRdMeterReadsLp) {
        return 1;
    }
}
